import numpy as np
import networkx as nx
import itertools
import matplotlib.pyplot as plt
import random
Num_of_nodes=10
Density_of_network=0.2
Num_of_node_status=5

Num_of_node_true_value=1
Num_of_edge_true_value=2

M=np.floor(Num_of_nodes*(Num_of_nodes-1)*Density_of_network) 
adjacency_matrix=np.zeros((Num_of_nodes,Num_of_nodes),dtype=int)
while M>0:
    location=np.random.choice(Num_of_nodes,2,replace=False)
    if adjacency_matrix[location[0],location[1]]==0:
        adjacency_matrix[location[0],location[1]]=1
        M-=1

importance_matrix=np.random.randint(1,Num_of_nodes**2,size=(Num_of_nodes,Num_of_nodes))
for i in range(Num_of_nodes):
    for j in range(Num_of_nodes):
        if j!=i and adjacency_matrix[i,j]==0:
            importance_matrix[i,j]=0
            
True_values=np.empty((Num_of_nodes,Num_of_nodes),dtype=set)
for i in range(Num_of_nodes):
    for j in range(Num_of_nodes):
        True_values[i,j]=set()
        if j==i:
            tmp=random.sample(list(range(Num_of_node_status)),Num_of_node_true_value)
            True_values[j,j].update(tmp)
        else:
            tmp=random.sample(list(itertools.product(range(Num_of_node_status),repeat=2)),Num_of_edge_true_value)
            True_values[i,j].update(tmp)
            
def Is_internal_alignment(decision_node,choice,True_values):
    if choice in True_values[decision_node,decision_node]:
        return 1
    else:
        return 0

def Is_external_alignment(origin,terminus,choice_pair,True_values):
    if choice_pair in True_values[origin,terminus]:
        return 1
    else:
        return 0
    
def Project_perf(Project_status,importance_matrix,True_values):
    
    N=np.size(Project_status)
    Total=0
  
    for i in range(N):
        for j in range(N):
            if j==i:
                Total=Total+importance_matrix[i][j]*Is_internal_alignment(j,Project_status[j],True_values)
            else:
                Total=Total+importance_matrix[i][j]*Is_external_alignment(i,j,(Project_status[i],Project_status[j]),True_values)
                           
    return Total